package org.hh.jga.concurrent;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * For loop chunk
 * 
 * @author Hong Hong
 *
 * @param <T> type of element
 */
class LoopChunk<T> implements Runnable {
	protected List<T> m_itemList;
	protected final LoopExceptionHandler<T> m_handler;
	protected final LoopBody<T> m_body;
	protected final Semaphore m_waiter;
	protected int m_chunkSize;
	
	public void run() {
		for(T item : m_itemList) {
			try {
				m_body.body(item);
			} catch (Exception e) {
				if(m_handler != null)
					m_handler.handle(item, e);
			}
		}
		m_waiter.release();
	}
	public LoopChunk(Semaphore waiter, LoopBody<T> body, LoopExceptionHandler<T> handler, int chunkSize) {
		assert body != null && waiter != null;
		m_waiter = waiter;
		m_body = body;
		m_handler = handler;
		m_chunkSize = chunkSize;
	}
	public LoopChunk(Semaphore waiter, LoopBody<T> body, LoopExceptionHandler<T> handler, int chunkSize, Iterator<T> itemList) {
		this(waiter, body, handler, chunkSize);
		setChunk(itemList);
	}	
	public boolean setChunk(Iterator<T> itemList) {
		int index = 0;
		ArrayList<T> list = new ArrayList<T>(m_chunkSize);
		while(itemList.hasNext() && index < m_chunkSize) {
			list.add(itemList.next());
			++index;
		}
		m_itemList = list;
		return index < m_chunkSize;
	}
	public boolean setChunk(Iterator<T> itemList, int num) {
		m_chunkSize = num;
		return setChunk(itemList);
	}
	public void setChunk(List<T> itemList) {
		m_itemList = itemList;
	}
	
}
